package com.lock.class1;


/**
 * synchronized (类.class)
 * 
 * @author onlyone
 */
public class SynchronizedClass {

    /**
     * 这段代码展示了使用 synchronized 关键字实现同步的一个例子。
     * 在方法 m1() 中，使用 synchronized (SynchronizedClass.class) 的方式对 SynchronizedClass 类对象进行了加锁操作，这意味着当有其他线程想要执行同步代码块时，必须先获取到 SynchronizedClass.class 对象的锁。
     * 在 m1() 方法中，首先会输出 "m1方法获得锁"，表示线程成功获取到锁并执行同步代码块。
     * 然后通过 Thread.sleep(1200) 方法模拟执行一些耗时操作，期间其他线程如果想要执行同步代码块，则必须等待当前线程执行完毕并释放锁。
     * 最后输出 "m1方法释放锁"，表示当前线程执行完同步代码块后释放了锁。
     * 这样可以保证同一时刻只有一个线程可以执行 m1() 方法中的同步代码块，从而保证了线程安全性。
     */
    public void m1() {
        synchronized (SynchronizedClass.class) {
            System.out.println("m1方法获得锁");
            try {
                Thread.sleep(1200);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("m1方法释放锁");
        }
    }

    public void m2() {
        synchronized (SynchronizedClass.class) {
            System.out.println("m2方法获得锁");
            try {
                Thread.sleep(1200);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("m2方法释放锁");

        }
    }

    static class Task1 implements Runnable {

        private SynchronizedClass synchronizedClass;

        public Task1(SynchronizedClass synchronizedClass){
            this.synchronizedClass = synchronizedClass;
        }

        @Override
        public void run() {
            synchronizedClass.m1();
        }
    }

    static class Task2 implements Runnable {

        private SynchronizedClass synchronizedClass;

        public Task2(SynchronizedClass synchronizedClass){
            this.synchronizedClass = synchronizedClass;
        }

        @Override
        public void run() {
            synchronizedClass.m2();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynchronizedClass syn = new SynchronizedClass();
        new Thread(new Task1(syn)).start();
        new Thread(new Task2(syn)).start();

        // 主线程阻塞，防止jvm提早退出
        Thread.sleep(150000);
    }

}
